package gdut.imis.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import gdut.imis.Utils.Constants;
import gdut.imis.Utils.Result;
import gdut.imis.domain.FileType;
import gdut.imis.domain.FileWritePermission;
import gdut.imis.domain.FileWritePermissionApplication;
import gdut.imis.domain.User;
import gdut.imis.enums.HasHandledEnum;
import gdut.imis.enums.Status;
import gdut.imis.mapper.FileTypeMapper;
import gdut.imis.mapper.FileWritePermissionApplicationMapper;
import gdut.imis.service.FileWritePermissionApplicationService;
import gdut.imis.service.FileWritePermissionService;
import gdut.imis.vo.FileWritePermissionApplicationVo;
import gdut.imis.vo.UserLoginVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author JiaFu
 * @Date 2023/4/7 22:36
 */
@Service
@RequiredArgsConstructor
public class FileWritePermissionApplicationServiceImpl extends ServiceImpl<FileWritePermissionApplicationMapper, FileWritePermissionApplication> implements FileWritePermissionApplicationService {
    private final FileWritePermissionService fileWritePermissionService;

    private final FileWritePermissionApplicationMapper fileWritePermissionApplicationMapper;

    private final FileTypeMapper fileTypeMapper;

    @Value("${env-file-path.base-path}")
    private String basePath;//证明文件上传的根路径

    /***
     * 用户（管理员或教师）申请档案录入权限
     * @param: file
     * @param: fileType
     * @return Result
     */
    @Override
    public Result applyFileWritePermission(MultipartFile file, FileType fileType) throws IOException {
        //校验参数合法性
        if (Objects.isNull(file) || Objects.isNull(fileType) || (fileType.getId() == null)) {
            return Result.errorWithArgs(Status.REQUEST_PARAMS_NOT_VALID_ERROR, "参数file/id不能为空");
        }
        //获取用户信息
        UserLoginVo userLoginVo = (UserLoginVo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (userLoginVo.getIsManager()) {//管理员用户不可以申请档案录入权限，档案录入由老师和学生申请即可，管理员审核权限
            return Result.errorWithArgs(Status.FAILED, "管理员不可申请档案录入权限");
        }
        User user = userLoginVo.getUser();
        //判断用户是否已申请过该档案录入权限，并且未处理
        LambdaQueryWrapper<FileWritePermissionApplication> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(FileWritePermissionApplication::getUserId, user.getId())
                .eq(FileWritePermissionApplication::getStatus, 1)
                .eq(FileWritePermissionApplication::getFileTypeId, fileType.getId());
        FileWritePermissionApplication fileWritePermissionApplication = this.getOne(queryWrapper);
        if (!Objects.isNull(fileWritePermissionApplication)) {
            FileType filetype = fileTypeMapper.selectById(fileWritePermissionApplication.getFileTypeId());
            return Result.errorWithArgs(Status.FAILED, "用户已提交过" + filetype.getIntroduction() + "录入权限申请");
        }
        //原始证明文件文件名
        String filename = file.getOriginalFilename();
        int suffixIndex = filename.lastIndexOf(".");
        String suffix = filename.substring(suffixIndex);//文件后缀名
        filename = UUID.randomUUID().toString().replaceAll("-", "").concat(suffix);
        String path = basePath + "prov_files" + Constants.SEPARATOR;//存储申请权限证明文件的文件夹路径
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        path = path.concat(filename);
        file.transferTo(new File(path));
        //存储用户申请权限信息到数据库
        FileWritePermissionApplication application = new FileWritePermissionApplication();
        application.setFileTypeId(fileType.getId());
        application.setUserId(user.getId());
        application.setProveUrl(path);
        boolean flag = this.save(application);
        if (flag) {
            return Result.success();
        }
        return Result.error(Status.FAILED);
    }

    /***
     * 用户查询档案录入权限申请情况
     * @return Result
     */
    @Override
    public Result getFileWritePermissionApplyResult() {
        UserLoginVo userLoginVo = (UserLoginVo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (userLoginVo.getIsManager()) {
            return Result.errorWithArgs(Status.FAILED, "管理员不可查");
        }
        List<FileWritePermissionApplicationVo> resList = fileWritePermissionApplicationMapper.getFileWritePermissionApplyResult(userLoginVo.getUser().getId());
        if (CollectionUtils.isEmpty(resList)) {
            return Result.errorWithArgs(Status.FAILED, "用户还没有申请过任何档案录入权限");
        }
        resList = resList.stream().map(fileWritePermissionApplicationVo -> {
            HasHandledEnum status = fileWritePermissionApplicationVo.getStatus();
            if (status == HasHandledEnum.NOT_HANDLED) {
                fileWritePermissionApplicationVo.setResult(null);
            }
            return fileWritePermissionApplicationVo;
        }).collect(Collectors.toList());
        return Result.success(resList);
    }


    @Override
    public Result getPageFileWritePersission(Long universityId, Integer pageNo, Integer pageSize) {
        Page<FileWritePermissionApplicationVo> page = new Page<>();
        page.setCurrent(pageNo);
        page.setSize(pageSize);
        Page<FileWritePermissionApplicationVo> resPage = fileWritePermissionApplicationMapper.getPageFileWritePermission(universityId, page);
        if (resPage.getTotal() > 0) {
            return Result.success(resPage);
        }
        return Result.errorWithArgs(Status.FAILED, "没有查到任何正在申请的档案录入权限信息");
    }

    /***
     * 处理档案录入权限申请（三级管理员才有的权限）
     * @param: fileWritePermissionApplication
     * @return Result
     */
    @Override
    @Transactional
    public Result handleFileWritePermissionApply(FileWritePermissionApplication fileWritePermissionApplication) {
        if (Objects.isNull(fileWritePermissionApplication)) {
            return Result.errorWithArgs(Status.REQUEST_PARAMS_NOT_VALID_ERROR, "fileWritePermissionApply");
        }
        UserLoginVo userLoginVo = (UserLoginVo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Integer id = userLoginVo.getManager().getId();
        fileWritePermissionApplication.setManagerId(id);
        //更新档案录入权限申请的处理状态
        boolean flag = this.updateById(fileWritePermissionApplication);
        //如果审核结果为通过，则新增用户档案录入权限
        if (fileWritePermissionApplication.getResult().getType() == 0) {
            //新增用户档案权限
            FileWritePermission fileWritePermission = new FileWritePermission();
            fileWritePermission.setUserId(fileWritePermissionApplication.getUserId());
            fileWritePermission.setFileTypeId(fileWritePermissionApplication.getFileTypeId());
            boolean flag2 = fileWritePermissionService.save(fileWritePermission);
            if (flag && flag2) {
                return Result.success("处理成功", null);
            }
            return Result.errorWithArgs(Status.FAILED,"处理失败");
        }
        if(flag){
            return Result.success();
        }
        return Result.errorWithArgs(Status.FAILED, "处理失败");
    }
}
